package com.surprise.base.slo;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Sets;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
public class SingleMap<K, V> implements Map<K, V> {
    private K key;
    private V value;

    @Override
    public int size() {
        return key == null ? 0 : 1;
    }

    @Override
    public boolean isEmpty() {
        return key == null;
    }

    @Override
    public boolean containsKey(Object key) {
        if(this.key == null) {
            return false;
        }
        return this.key.equals(key);
    }

    @Override
    public boolean containsValue(Object value) {
        if(this.value == null) {
            return false;
        }
        return this.value.equals(value);
    }

    @Override
    public V get(Object key) {
        if (containsKey(key)) {
            return value;
        }
        return null;
    }

    @Override
    public V put(K key, V value) {
        if(key == null || value == null) {
            return null;
        }
        V oldValue = this.value;
        this.key = key;
        this.value = value;
        return oldValue;
    }

    @Override
    public V remove(Object key) {
        if(containsKey(key)) {
            V oldValue = this.value;
            this.key = null;
            this.value = null;
            return oldValue;
        }
        return null;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        if (m == null || m.size() == 0) {
            return;
        }
        if (m.size() == 1) {
            m.forEach((k, v) -> {
                if (k != null && v != null) {
                    this.key = k;
                    this.value = v;
                }
            });
        }
        throw new UnsupportedOperationException("map size > 1");
    }

    @Override
    public void clear() {
        this.key = null;
        this.value = null;
    }

    @Override
    public Set<K> keySet() {
        return null;
    }

    @Override
    public Collection<V> values() {
        if(value == null) {
            return Collections.emptyList();
        }
        return Arrays.asList(value);
    }

    @Override
    public Set<java.util.Map.Entry<K, V>> entrySet() {
        return Sets.newHashSet(new Node<K, V>(key, value));
    }
    
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Node<K, V> implements Map.Entry<K, V> {
        private K key;
        private V value;
        
        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(V value) {
            throw new UnsupportedOperationException("map size > 1");
        }
    }

}
